import { Commit, createStore } from 'vuex'
import axios, { AxiosRequestConfig } from 'axios'

// 封装get请求 -- Commit就是commit的类型
const getAndCommit = async (url: string, mutationName: string, commit: Commit) => {
    // commit('setLoading', true) //开始
    const { data } = await axios.get(url)
    commit(mutationName, data)

    // commit('setLoading', false) //结束
}

// 封装 post 请求--payload post携带的值
const PostAndCommit = async (url: string, mutationName: string, commit: Commit, payload: any) => {
    const { data } = await axios.post(url, payload)
    commit(mutationName, data)
}

// 封装Patch
const asyncAndCommit = async (url: string, mutationName: string, commit: Commit, config: AxiosRequestConfig = { method: 'get' }) => {
    const { data } = await axios(url, config)
    commit(mutationName, data)
    return data
}

//当前是否登录
export interface Userprops {
    isLogin: boolean,
    nickName?: string,
    _id?: string,
    column?: string//用户自己专栏的id
    description?: string
    avatar?: ImagePrpos
}

// 图片的描述
export interface ImagePrpos {
    _id?: string,
    url?: string,
    createdAt?: string
}
//专栏列表
export interface ColumnProps {
    _id: string,
    title: string, //标题
    avatar?: ImagePrpos, //头像
    description: string //描述
}

//文章列表
export interface PostProps {
    _id?: string,
    title: string,
    excerpt?: string,
    content?: string,
    image?: ImagePrpos | string,
    createdAt?: string,//发布事件
    column: string //文章id，因为你点开的文章和你的文章id做匹配
    author?: string | Userprops
}

// 声明错误
export interface GolbalErrorProps {
    status: boolean,
    message?: string
}
// 上传成功  p泛型
export interface ResponseType<p = []> {
    code: number,
    msg: string,
    data: p
}

//如果想在其他页面使用，直接导出
export interface GolbalDataProps {
    columns: ColumnProps[],
    posts: PostProps[],
    user: Userprops,
    loading: boolean,
    token: string,
    error: GolbalErrorProps,

}



const store = createStore<GolbalDataProps>({
    state: {
        columns: [],
        posts: [],
        user: { isLogin: false },
        loading: false,
        token: localStorage.getItem('token') || '',
        error: { status: false },
    },
    // Vuex允许我们在store中定义‘getter'(可以认为是 store 的计算属性)
    // getter的返回值会根据它的依赖被缓存起来，且只有当他的依赖值发生了改变才会被重新计算
    getters: {
        //当前跳转的专栏详情是否是我点击的专栏--c.id是我们点击的id和获取到地址上的id是否一样
        getColumnById: (state) => (cid: string) => {
            return state.columns.find(c => c._id === cid)
        },
        //    column文章 作者的id
        getPostById: (state) => (cid: string) => {
            return state.posts.filter(post => post.column === cid)
        },
        getDetailById: (state) => (cid: number) => {
            return state.posts[cid]
        }

    },
    mutations: {
        //登录
        login(state, rawData) {
            console.log(rawData);
            // state.token = rawData.data
            const { token } = rawData.data
            // console.log(token); 
            state.token = token
            // 保存token值
            localStorage.setItem('token', token)
            // 定义请求头--您可以指定默认配置，它将作用于每个请求。发送请求时，携带token
            axios.defaults.headers.common.Authorization = `Bearer ${token}`
            // state.user = { ...state.user, isLogin: true, nickName: '土豆' }
        },
        // 删除token
        logout(state) {
            state.token = ''
            localStorage.removeItem('token')
            delete axios.defaults.headers.common.Authorization
        },
        fetchCurrentUser(state, rawData) {
            console.log(rawData);
            // rawData是个对象，展开他
            state.user = { isLogin: true, ...rawData.data }
        },

        // 专栏列表
        fetchColumns(state, rwaData) {
            console.log(rwaData);
            state.columns = rwaData.data.list
        },
        // 文章详情
        fetchColumn(state, rawData) {
            state.columns = [rawData.data]
        },
        // 文章列表
        fetchPosts(state, rwaData) {
            console.log(rwaData);

            state.posts = rwaData.data.list

        },
        fetchPost(state, rawData) {
            console.log(rawData.data);
            state.posts[rawData.data._id] = rawData.data
        },
        //新建文章
        createPost(state, newPost) {
            console.log(newPost);
            state.posts.push(newPost)
        },
        // 更新文章
        updatePost(state, { data }) {
            state.posts = state.posts.map(post => {
                if (post._id === data._id) {
                    return data
                }
                return post
            })
        },
        // 删除文章
        deletePost(state, data) {
            state.posts = state.posts.filter(post => post._id !== data.id)
        },
        setLoading(state, status) {
            state.loading = status //true和false
        },

        // 登录错误
        setError(state, e: GolbalErrorProps) {
            console.log(e);
            state.error = e
        }
    },
    // 类似于 mutations
    // actions 提交 mutations -- actions不能直接改变值，
    actions: {


        // 专栏详情
        fetchColumns(context) {
            // 普通的
            // axios.get('/columns').then(resp => {
            //     context.commit('fetchColumns', resp.data)
            // })
            // 使用async和await
            // const { data } = await axios.get('/columns')
            // context.commit('fetchColumns', data)
            // 封装的
            // getAndCommit('/columns', 'fetchColumns', context.commit)

            asyncAndCommit('/columns', 'fetchColumns', context.commit)
        },
        // 文章详情
        fetchColumn({ commit }, cid) {
            // 普通的
            // axios.get(`/columns/${cid}`).then(resq => {
            //     commit('fetchColumn', resq.data)
            // })
            // 使用async和await
            // const { data } = await axios.get(`/columns/${cid}`)
            // commit('fetchColumn', data)
            getAndCommit(`/columns/${cid}`, 'fetchColumn', commit)
        },
        // 文章列表
        fetchPosts({ commit }, cid) {
            // 普通的
            // axios.get(`/columns/${cid}/posts`).then(resp => {
            //     commit('fetchPosts', resp.data)
            // })
            // 使用async和await
            // const { data } = await axios.get(`/columns/${cid}/posts`)
            // commit('fetchPosts', data)
            getAndCommit(`/columns/${cid}/posts`, 'fetchPosts', commit)
        },
        // 单个文章详情
        fetchPost({ state, commit }, id) {
            // 把id为我们点击文章的所有数据拿过来
            const currentPost = state.posts[id]
            if (!currentPost || !currentPost.content) {
                return getAndCommit(`/posts/${id}`, 'fetchPost', commit)
            } else {
                return Promise.resolve({ data: currentPost })
            }
        },
        // 新建文章
        createPost({ commit }, payload) {
            console.log(payload);
            PostAndCommit('/posts', 'createPost', commit, payload)
        },
        // 更新文章
        updatePost({ commit }, { id, payload }) {
            return asyncAndCommit(`/posts/${id}`, 'updatePost', commit, {
                method: 'patch',
                data: payload
            })
        },
        // 删除文章
        deletePost({ commit }, id) {
            return asyncAndCommit(`posts/${id}`, 'deletePost', commit, { method: 'delete' })
        },
        // 登录
        login({ commit }, payload) {
            console.log(payload);
            return PostAndCommit('/user/login', 'login', commit, payload)
        },
        // 登录信息
        fetchCurrentUser({ commit }) {
            getAndCommit('/user/current', 'fetchCurrentUser', commit)
        },
        loginAndFecth({ dispatch }, loginData) {
            return dispatch('login', loginData).then(() => {
                return dispatch('fetchCurrentUser')
            })
        }
    },
    modules: {}
})



export default store